home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume6 / qterm < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  11.1 KB

  1. Subject: v06i020:  qterm: Query Terminal for terminal type (qterm)
  2. Reply-To: mcooper@usc-oberon.arpa
  3. Newsgroups: mod.sources
  4. Approved: rs@mirror.UUCP
  5.  
  6. Submitted by: mcooper@usc-oberon.ARPA
  7. Mod.sources: Volume 6, Issue 20
  8. Archive-name: qterm
  9.  
  10. #!/bin/sh
  11. # This is a shell archive, meaning:
  12. # 1. Remove everything above the #!/bin/sh line.
  13. # 2. Save the resulting text in a file.
  14. # 3. Execute the file with /bin/sh (not csh) to create the files:
  15. #    README
  16. #    Makefile
  17. #    qterm.c
  18. #    qterm.1
  19. # This archive created: Wed Jun 18 16:02:27 1986
  20. # By:    Michael A. Cooper (USC Computing Services, Los Angeles)
  21. export PATH; PATH=/bin:$PATH
  22. echo shar: extracting "'README'" '(1050 characters)'
  23. if test -f 'README'
  24. then
  25.     echo shar: over-writing existing file "'README'"
  26. fi
  27. cat << \SHAR_EOF > 'README'
  28.  
  29.          Q T E R M  -  Q U E R Y   T E R M I N A L
  30.  
  31.                       Revision 1.11
  32.  
  33.     Qterm is a program that queries terminals to find out what kind
  34. of terminal is responding.  It is useful to automagically define your
  35. terminal type.  It prints the name of the terminal (compatible, hopefully,
  36. with a termcap/terminfo name) such as "vt100" to standard output.
  37. See the manual for details.
  38.  
  39.     Qterm was written under 4.2BSD and will probably run without 
  40. modification on other Berkeley Unix systems.  It will require some
  41. minor tweaking to work under USG (System III & V.?, V?).  Most of this
  42. should be only in setting/unsetting cbreak and echo modes.  If you
  43. do port it to Sys V, please send me a copy and I'll incorporate it into
  44. my version.
  45.  
  46.     If you add any new terminal's to the master table, please send
  47. me the output of a "qterm -s" and I'll add it to my table.
  48.  
  49.                 mike
  50.  
  51.  
  52. Michael Cooper, U of Southern California Computing Services, (213) 743-3462
  53.   UUCP: {sdcrdcf, uscvax}!usc-oberon!mcooper
  54.   ARPA: mcooper@usc-oberon.arpa         BITNET: mcooper@uscvaxq
  55. SHAR_EOF
  56. echo shar: extracting "'Makefile'" '(97 characters)'
  57. if test -f 'Makefile'
  58. then
  59.     echo shar: over-writing existing file "'Makefile'"
  60. fi
  61. cat << \SHAR_EOF > 'Makefile'
  62. qterm: qterm.c
  63.     cc -O qterm.c -o qterm
  64.  
  65. shar:
  66.     shar README Makefile qterm.c qterm.1 > qterm.shar
  67. SHAR_EOF
  68. echo shar: extracting "'qterm.c'" '(7498 characters)'
  69. if test -f 'qterm.c'
  70. then
  71.     echo shar: over-writing existing file "'qterm.c'"
  72. fi
  73. cat << \SHAR_EOF > 'qterm.c'
  74. #ifndef lint
  75. static char *RCSid = "$Header: qterm.c,v 1.11 86/06/18 15:58:45 mcooper Release $";
  76. #endif
  77.  
  78. /*
  79.  *------------------------------------------------------------------
  80.  *
  81.  * $Source: /usr/src/local/qterm/RCS/qterm.c,v $
  82.  * $Revision: 1.11 $
  83.  * $Date: 86/06/18 15:58:45 $
  84.  * $State: Release $
  85.  * $Author: mcooper $
  86.  * $Locker: mcooper $
  87.  *
  88.  *------------------------------------------------------------------
  89.  *
  90.  * Michael Cooper (mcooper@usc-oberon.arpa)
  91.  * University Computing Services,
  92.  * University of Southern California,
  93.  * Los Angeles, California,   90089-0251
  94.  * (213) 743-3469
  95.  *
  96.  *------------------------------------------------------------------
  97.  * $Log:    qterm.c,v $
  98.  * Revision 1.11  86/06/18  15:58:45  mcooper
  99.  * Cleanup for release.
  100.  * 
  101.  * Revision 1.10  86/06/17  23:06:55  mcooper
  102.  * Added Unix PC responses.
  103.  * 
  104.  * Revision 1.9  86/06/16  14:19:09  mcooper
  105.  * Added vt100 responses from vt100 manual.
  106.  * 
  107.  * Revision 1.8  86/06/16  13:23:40  mcooper
  108.  * Print additional information about
  109.  * what the actual terminal is.
  110.  * 
  111.  * Revision 1.7  86/06/12  10:59:27  mcooper
  112.  * *** empty log message ***
  113.  * 
  114.  * Revision 1.6  86/06/11  19:48:35  mcooper
  115.  * Added alternate string and table entries for concepts.
  116.  * 
  117.  * Revision 1.5  86/05/19  12:30:32  mcooper
  118.  * General clean up.
  119.  * 
  120.  * Revision 1.4  86/05/18  17:56:11  mcooper
  121.  * Added another vt100.  This one is for when you rlogin
  122.  * from a Pro 2.9bsd host on a HDS Concept.
  123.  * 
  124.  * Revision 1.3  86/05/08  09:24:13  mcooper
  125.  * Added another vt100 description.
  126.  * 
  127.  * Revision 1.2  86/05/06  18:23:35  mcooper
  128.  * More cleanup - de-linted (almost).
  129.  * 
  130.  * Revision 1.1  86/05/06  14:56:57  mcooper
  131.  * Initial revision
  132.  * 
  133.  *------------------------------------------------------------------
  134.  */
  135.  
  136. /*
  137.  * qterm - Query Terminal
  138.  *
  139.  * qterm is used to query a terminal to determine the name of the terminal.
  140.  * This is done by sending a fairly universal string "\33Z" to the terminal,
  141.  * reading in a response, and comparing it against a master table of responses
  142.  * and names.  The "name" printed to standard output should be one found in
  143.  * the termcap(5) database.
  144.  *
  145.  * Putting a line in your .login files such as:
  146.  *
  147.  *    setenv TERM `qterm`
  148.  *
  149.  * will set your terminal type automagically.
  150.  * 
  151.  * If you add a terminal to the master table, please also send me a copy
  152.  * so that I may put it into my version.
  153.  *
  154.  * Michael Cooper
  155.  * ARPA:     mcooper@usc-oberon.ARPA
  156.  * UUCP:     mcooper@usc-oberon.UUCP
  157.  * BITNET:    mcooper@uscvaxq.BITNET
  158.  */
  159.  
  160. #include <stdio.h>
  161. #include <sgtty.h>
  162. #include <signal.h>
  163. #include <sys/ioctl.h>
  164. #include <sys/file.h>
  165.  
  166. #define SEND        "\033Z"        /* send this to query terminal */
  167. #define ALTSEND        "\033[c"    /* alternate string */
  168.  
  169. #define TRUE        1
  170. #define FALSE        0
  171.  
  172. #define T_STR        0
  173. #define T_NAME        1
  174. #define T_LNAME        2
  175.  
  176. /*
  177.  * The Master Table
  178.  */
  179. char *terms[] = {
  180. /*  Terminal Sends:        Terminal Name:     Real Name:         */
  181. /*    ---------------        --------------     ----------         */
  182.     "\33[?1;0c",        "vt100",        "Base vt100",
  183.     "\33[?1;1c",        "vt100",        "vt100 with STP",
  184.     "\33[?1;2c",        "vt100",        "ANSI/VT100 Clone",
  185.     "\33[?1;3c",        "vt100",        "vt100 with AVO and STP",
  186.     "\33[?1;4c",        "vt100",        "vt100 with GPO",
  187.     "\33[?1;5c",        "vt100",        "vt100 with GPO and STP",
  188.     "\33[?1;6c",        "vt100",        "vt100 with GPO and AVO",
  189.     "\33[?1;7c",        "vt100",        "vt100 with GPO, STP, and AVO",
  190.     "\33[?12c",            "vt100",        "Generic vt100",
  191.     "\33[?6c",            "vt100",        "Generic vt100",
  192.     "\33[?8c",            "vt100",        "TeleVideo 970",
  193.     "\33[0n",            "vt100",        "AT&T Unix PC 7300",
  194.     "\33[?l;0c",        "vt100",        "AT&T Unix PC 7300",
  195.     "\33[=1;1c",        "avt-4p-s",        "Concept with 4 pages memory",
  196.     "\33[=1;2c",        "avt-8p-s",        "Concept with 8 pages memory",
  197.     "\33iBO",            "z29",            "Zenith z29 in zenith mode",
  198.     "\33/K",            "z29",            "Zenith z29 in zenith mode",
  199.     "\33/Z",            "vt52",            "Generic vt52",
  200.     "\33[?12;7;0;102c",    "vt125",        "DEC Pro 350 in vt125 mode",
  201.     "\33[?10c",            "la120",        "DEC Writer III",
  202.     NULL
  203. };
  204.  
  205. struct sgttyb _tty;
  206. int _tty_ch = 2;
  207.  
  208. #define crmode()     (_tty.sg_flags |= CBREAK,  stty(_tty_ch,&_tty))
  209. #define nocrmode()     (_tty.sg_flags &= ~CBREAK, stty(_tty_ch,&_tty))
  210. #define echo()         (_tty.sg_flags |= ECHO,    stty(_tty_ch,&_tty))
  211. #define noecho()     (_tty.sg_flags &= ~ECHO,   stty(_tty_ch,&_tty))
  212.  
  213. #define SIZE         512
  214. #define CMASK         0377
  215. #define ESC            '\033'
  216.  
  217. static char buf[SIZE];
  218. static char *progname;
  219. int debug;                    /* debug mode             */
  220. int aflag;                    /* alternate string     */
  221. int sflag;                    /* print strings        */
  222. int qflag;                    /* quiet mode             */
  223.  
  224. main(argc, argv)
  225. char *argv[];
  226. {
  227.     register int i, x;
  228.     register char c;
  229.     int finish();
  230.     int still_ok = 1;
  231.  
  232.     progname = argv[0];
  233.  
  234.     for (x = 1; x < argc; x++) {
  235.         if (argv[x][0] != '-')
  236.             break;
  237.         switch (argv[x][1]) {
  238.             case 'a':
  239.                 aflag = TRUE;
  240.                 break;
  241.             case 't':
  242.             case 's':
  243.                 sflag = TRUE;
  244.                 break;
  245.             case 'q':
  246.                 qflag = TRUE;
  247.                 break;
  248.             case 'd':
  249.                 debug = TRUE;
  250.                 break;
  251.             default:
  252.                 usage();
  253.                 exit(1);
  254.         }
  255.     }
  256.  
  257.     setbuf(stdout, 0);
  258.  
  259.     if(debug)
  260.         fprintf(stderr,"[ %s debug mode enabled ]\n\n", progname);
  261.  
  262.     if(!isatty(0))
  263.         fprintf(stderr,"Not a tty.\n");
  264.  
  265.     if(gtty(_tty_ch, &_tty) < 0) {
  266.         perror("gtty");
  267.         exit(1);
  268.     }
  269.     if(crmode() < 0) {
  270.         perror("crmode");
  271.         exit(1);
  272.     }
  273.     if(noecho() < 0) {
  274.         perror("noecho");
  275.         exit(1);
  276.     }
  277.  
  278.     (void) signal(SIGALRM, finish);
  279.     (void) alarm(2);
  280.  
  281.     if(debug) {
  282.         fprintf(stderr, "[ sending string: ");
  283.         decode((aflag) ? ALTSEND : SEND);
  284.         fprintf(stderr, " ]\n");
  285.     }
  286.     fprintf(stderr, (aflag) ? ALTSEND : SEND);
  287.     (void) fflush(stdout);
  288.     (void) fflush(stderr);
  289.     buf[0] = getch();
  290.     if(buf[0] == ESC) {
  291.         i = 0;
  292.         while(still_ok) {
  293.             c = getch();
  294.             buf[++i] = c;
  295.             /*
  296.              * Most ANSI comptibles have 'c' for the
  297.              * last char printed.
  298.              */
  299.             if(c == 'c')
  300.                 still_ok = 0;
  301.         }
  302.         if(debug)
  303.             fprintf(stderr,"\n[ Received 'c' terminator. ]\n");
  304.     } else {
  305.         if(!qflag)
  306.             fprintf(stderr,
  307.             "Terminal not recognized - defaults to \"dumb\".\n");
  308.         printf("dumb\n");
  309.         (void) nocrmode();
  310.         (void) echo();
  311.         exit(1);
  312.     }
  313.     finish();
  314. }
  315.  
  316. /*
  317.  * finish - this is where we come no matter what.
  318.  */
  319. finish()
  320. {
  321.     (void) nocrmode();
  322.     (void) echo();
  323.     compare();
  324.     exit(0);
  325. }
  326.  
  327. /*
  328.  * compare - actually compare what we received against the terminal
  329.  *         tables.
  330.  */
  331. compare()
  332. {
  333.     char *term, *longname;
  334.     register int i = 0;
  335.     int okay = 1;
  336.     int len;
  337.  
  338.     if(debug || sflag) {
  339.         len = strlen(buf);
  340.         fprintf(stderr, "%s receives %d character%c: ", progname,
  341.             len, (len == 1) ? 0 : 's');
  342.         decode(buf);
  343.         fprintf(stderr, "\n");
  344.     }
  345.  
  346.     while(okay) {
  347.         if(terms[i] == NULL) {
  348.             okay = 0;
  349.             term = "dumb";
  350.             buf[0] = NULL;
  351.             continue;
  352.         }
  353.         if(strcmp(buf, terms[i + T_STR]) == 0) {
  354.             term = terms[i + T_NAME];
  355.             longname = terms[i + T_LNAME];
  356.             okay = 0;
  357.         }
  358.         i += 3;
  359.     }
  360.  
  361.     if(buf[0] != NULL) {
  362.         if(!qflag)
  363.             if(*longname)
  364.                 fprintf(stderr, "Terminal recognized as %s (%s)\n", 
  365.                     term, longname);
  366.             else
  367.                 fprintf(stderr, "Terminal recognized as %s\n", term);
  368.     } else {
  369.         if(!qflag)
  370.             fprintf(stderr, 
  371.               "Terminal NOT recognized - defaults to \"%s\".\n",
  372.               term);
  373.     }
  374.     printf("%s\n", term);
  375.         
  376. }
  377.  
  378. /*
  379.  * getch - read in a character at a time.
  380.  */
  381. getch()
  382. {
  383.     char c;
  384.  
  385.     (void) read(0, &c, 1);
  386.     return(c & CMASK);
  387. }
  388.  
  389. /*
  390.  * decode - print str in a readable fashion
  391.  */
  392. decode(str)
  393. char *str;
  394. {
  395.     while(*str) {
  396.         if (*str == ESC)
  397.             fprintf(stderr, "<esc> ");
  398.         else if((*str <= 33) || (*str >= 127))
  399.             fprintf(stderr,"\\%o ", *str);
  400.         else
  401.             fprintf(stderr,"%c ", *str);
  402.         *++str;
  403.     }
  404. }
  405.  
  406. usage()
  407. {
  408.     fprintf(stderr, "usage: %s [ -asq ]\n", progname);
  409. }
  410. SHAR_EOF
  411. echo shar: extracting "'qterm.1'" '(1406 characters)'
  412. if test -f 'qterm.1'
  413. then
  414.     echo shar: over-writing existing file "'qterm.1'"
  415. fi
  416. cat << \SHAR_EOF > 'qterm.1'
  417. .TH QTERM 1 5/6/86
  418. .ds ]W USC Computing Services
  419. .SH NAME
  420. qterm \- Query Terminal
  421. .SH SYNOPSIS
  422. qterm 
  423. [
  424. .B \-a
  425. ]
  426. [
  427. .B \-s
  428. ]
  429. [
  430. .B \-q
  431. ]
  432. .SH DESCRIPTION
  433. .I Qterm
  434. is used to query a terminal to determine its name.
  435. This is done by sending the fairly universal 
  436. string ``<ESCAPE>Z'' to the terminal,
  437. reading in a response, and comparing it against a master table of possible
  438. responses.
  439. The ``name'' printed to standard output should be one found in
  440. the
  441. .I termcap(5) 
  442. database.
  443. .PP
  444. Putting a line in your .login file such as:
  445. .sp 1
  446. .in +.5i
  447. setenv TERM `qterm`
  448. .in -.5i
  449. .sp 1
  450. should automagically set your terminal type.
  451. .SH OPTIONS
  452. .IP \-a
  453. Use the alternate string ``<ESCAPE>[c'' when asking the terminal to
  454. identify itself.  This string is recognized by most ANSI compatible
  455. terminals.
  456. .IP \-s
  457. Display the response received from
  458. the terminal in a ``nice'' fashion.
  459. .IP \-q
  460. Be ``quiet'' and only print the terminal name to standard
  461. output.
  462. .SH AUTHOR
  463. Michael A. Cooper, 
  464. .br
  465. USC Computing Services, Los Angeles.
  466. .SH FILES
  467. /etc/termcap    \- termcap(5) database
  468. .SH SEE ALSO
  469. termcap(5)
  470. .SH DIAGNOSTICS
  471. The message, ``Terminal not recognized - defaults to dumb.'', means
  472. that 
  473. .I qterm
  474. did not receive a response from the terminal, or the response
  475. did not match any that 
  476. .I qterm 
  477. has stored internally.  Use the \-s option to check to see which
  478. is the case.
  479. .SH BUGS
  480. Many terminals do not send a response at all.
  481. SHAR_EOF
  482. #    End of shell archive
  483. exit 0
  484.